package utils

import (
	"fmt"
	"strings"
	"sync"
	"unicode"

	"github.com/go-playground/validator/v10"
)

var lock = &sync.Mutex{}

var singleInstance *validator.Validate

func getInstance() *validator.Validate {
	if singleInstance == nil {
		lock.Lock()
		defer lock.Unlock()
		if singleInstance == nil {
			fmt.Println("Creating single instance now.")
			singleInstance = validator.New()
			singleInstance.RegisterValidation("CustomerValidation", CustomerValidationFunc) //注册自定义函数，前一个参数是struct里tag自定义，后一个参数是自定义的函数

			singleInstance.RegisterValidation("idCard", idCard)
		}
	}

	return singleInstance
}

// https://github.com/go-playground/validator
func Verify(st interface{}) (error error) {
	validate := getInstance()
	err := validate.Struct(st)
	return err
}

// 自定义函数
func CustomerValidationFunc(f1 validator.FieldLevel) bool {
	// f1 包含了字段相关信息
	// f1.Field() 获取当前字段信息
	// f1.Param() 获取tag对应的参数
	// f1.FieldName() 获取字段名称

	return f1.Field().String() == "jimmy"
}

// 校验一个身份证是否是合法的身份证
func idCard(f validator.FieldLevel) bool {
	var coefficient []int32 = []int32{7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2}
	var code []byte = []byte{'1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2'}

	idCardNo := f.Field().String()
	if len(idCardNo) != 18 {
		return false
	}

	idByte := []byte(strings.ToUpper(idCardNo))

	sum := int32(0)
	for i := 0; i < 17; i++ {
		sum += int32(byte(idByte[i])-byte('0')) * coefficient[i]
	}
	return code[sum%11] == idByte[17]
}

// 判断中文
func IsChineseChar(str string) bool {
	for _, r := range str {
		if !unicode.Is(unicode.Scripts["Han"], r) {
			return false
		}
	}
	return true
}

// 正则日期
// s := "Hello World, 123 Go!"
// //定义一个正则表达式reg，匹配Hello或者Go
// reg := regexp.MustCompile(`(Hell|G)o`)

// s2 := "2019-12-01,test"
// //定义一个正则表达式reg2,匹配 YYYY-MM-DD 的日期格式
// reg2 := regexp.MustCompile(`(\d{4})-(\d{2})-(\d{2})`)

// //最简单的情况，用“T替换”"-ab-axxb-"中符合正则"a(x*)b"的部分
// reg3 := regexp.MustCompile("a(x*)b")
// fmt.Println(re.ReplaceAllString("-ab-axxb-", "T")) // -T-T-

// //${1}匹配"Hello World, 123 Go!"中符合正则`(Hell|G)`的部分并保留，去掉"Hello"与"Go"中的'o'并用"ddd"追加
// rep1 := "${1}ddd"
// fmt.Printf("%q\n", reg.ReplaceAllString(s, rep1)) // Hellddd World, 123 Gddd!

// //首先，"2019-12-01,test"中符合正则表达式`(\d{4})-(\d{2})-(\d{2})`的部分是"2019-12-01",将该部分匹配'(\d{4})'的'2019'保留，去掉剩余部分
// rep2 := "${1}"
// fmt.Printf("%q\n", reg2.ReplaceAllString(s2,rep2)) // 2019,test

// //首先，"2019-12-01,test"中符合正则表达式`(\d{4})-(\d{2})-(\d{2})`的部分是"2019-12-01",将该部分匹配'(\d{2})'的'12'保留，去掉剩余部分
//  rep3 := "${2}"
// fmt.Printf("%q\n", reg2.ReplaceAllString(s2,rep3)) // 12,test

// //首先，"2019-12-01,test"中符合正则表达式`(\d{4})-(\d{2})-(\d{2})`的部分是"2019-12-01",将该部分匹配'(\d{2})'的'01'保留，去掉剩余部分,并追加"13:30:12"
// rep4 := "${3}:13:30:12"
// fmt.Printf("%q\n", reg2.ReplaceAllString(s2,rep4)) // 01:13:30:12,test
// }
